﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Odyssey.Classes;
using System.Threading;

namespace OdcDemo
{
    /// <summary>
    /// Demo data item which implements ILazyDataItem and IStatefulDataItem.
    /// ILazyDataItem responds to informations from an OdcListBox to change the state of IStatefulDataItem which is bound to a StatefulControl inside an ItemTemplate.
    /// </summary>
    public class ItemViewModel : INotifyPropertyChanged, ILazyDataItem, IStatefulDataItem
    {
        private bool abort = false;
        private static Random random = new Random();
        private bool isLoaded = false;
        private string state = "Unloaded";
        private string _lineOne;
        /// <summary>
        /// Sample ViewModel property; this property is used in the view to display its value using a Binding.
        /// </summary>
        /// <returns></returns>
        public string LineOne
        {
            get
            {
                return _lineOne;
            }
            set
            {
                if (value != _lineOne)
                {
                    _lineOne = value;
                    NotifyPropertyChanged("LineOne");
                }
            }
        }

        private string _lineTwo = "not loaded.";
        /// <summary>
        /// Sample ViewModel property; this property is used in the view to display its value using a Binding.
        /// </summary>
        /// <returns></returns>
        public string LineTwo
        {
            get
            {
                return _lineTwo;
                //return _lineTwo;
            }
            set
            {
                if (value != _lineTwo)
                {
                    _lineTwo = value;
                    NotifyPropertyChanged("LineTwo");
                }
            }
        }

        private string _lineThree;
        /// <summary>
        /// Sample ViewModel property; this property is used in the view to display its value using a Binding.
        /// </summary>
        /// <returns></returns>
        public string LineThree
        {
            get
            {
                return _lineThree;
            }
            set
            {
                if (value != _lineThree)
                {
                    _lineThree = value;
                    NotifyPropertyChanged("LineThree");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #region ILazyDataItem Members

        /// <summary>
        /// Occurs when the item is in the visible area and the OdcListBox changes it's IsScrolling value to true.
        /// In this case the state is changed to "Unloaded" which will be affected in the UI to hide LineTwo.
        /// </summary>
        public void Scroll()
        {
            abort = true;
            State = "Unloaded";
        }

        /// <summary>
        /// Occurs when the item becomes visible in an OdcListBox and OdcListBox.IsScrolling is set to false.
        /// In this case, the state is changed to "Loaded" after a random duration which simulates lazy loading.
        /// When the state changes to "Loaded" the StatefulControl which is bound to this control's State property performs a transition to fade in the text of LineTwo.
        /// 
        /// </summary>
        public void Load()
        {
            abort = false;
            if (isLoaded)
            {
                //State = DataItemState.Reloaded;
                State = "Loaded";
            }
            else
            {
                int ticks = random.Next(1500) + 500;
                ThreadPool.QueueUserWorkItem((o) =>
                    {
                        Thread.Sleep(ticks);
                        if (!abort)
                        {
                            Deployment.Current.Dispatcher.BeginInvoke(() =>
                                {
                                    State = "Loaded";
                                    isLoaded = true;
                                });
                        }
                    });
            }
        }

        /// <summary>
        /// Occurs when the item get outside the visible area in an OdcListBox, or when the data item is no longer bound with the UI.
        /// If necassary, the item can now unload data which consumes a lot of memory.
        /// </summary>
        public void Unload()
        {
            // the item is no longer visible, so abort async data loading, if possible:
            abort = true;

            State = "Unloaded";
        }

        #endregion

        #region IStatefulDataItem Members

        public string State
        {
            get { return state; }
            set
            {
                if (state != value)
                {
                    state = value;
                    NotifyPropertyChanged("State");
                    NotifyPropertyChanged("LineTwo");

                }
            }
        }

        #endregion
    }
}